/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * MainFrame.java
 *
 * Created on 5/10/2009, 3:54:45 AM
 */

package nz.ac.massey.spidernetpn.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Paint;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;

import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;

import java.util.List;
import java.util.Random;

import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JRootPane;

import org.apache.commons.collections15.Transformer;

import edu.uci.ics.jung.algorithms.layout.AbstractLayout;
import edu.uci.ics.jung.algorithms.layout.FRLayout;
import edu.uci.ics.jung.algorithms.layout.FRLayout2;
import edu.uci.ics.jung.algorithms.layout.Layout;
import edu.uci.ics.jung.graph.DirectedGraph;
import edu.uci.ics.jung.graph.DirectedSparseMultigraph;
import edu.uci.ics.jung.graph.SparseMultigraph;
import edu.uci.ics.jung.graph.event.GraphEvent.Edge;
import edu.uci.ics.jung.graph.util.EdgeType;
import edu.uci.ics.jung.graph.util.Graphs;
import edu.uci.ics.jung.graph.util.Pair;
import edu.uci.ics.jung.visualization.BasicVisualizationServer;
import edu.uci.ics.jung.visualization.GraphZoomScrollPane;
import edu.uci.ics.jung.visualization.VisualizationViewer;
import edu.uci.ics.jung.visualization.control.DefaultModalGraphMouse;
import edu.uci.ics.jung.visualization.decorators.ToStringLabeller;
import edu.uci.ics.jung.visualization.renderers.Renderer;

import nz.ac.massey.spidernetpn.database.GraphDatabase;
import nz.ac.massey.spidernetpn.webcrawler.FoundMaxException;
import nz.ac.massey.spidernetpn.webcrawler.WebCrawler;

/**
 * 
 * @author Eric
 */
public class MainFrame extends javax.swing.JFrame {

	/** Creates new form MainFrame */
	public MainFrame() {
		this.setDefaultCloseOperation(EXIT_ON_CLOSE);
		initComponents();
	}

	/**
	 * This method is called from within the constructor to initialize the form.
	 * WARNING: Do NOT modify this code. The content of this method is always
	 * regenerated by the Form Editor.
	 */
	@SuppressWarnings("unchecked")
	// <editor-fold defaultstate="collapsed"
	// desc="Generated Code">//GEN-BEGIN:initComponents
	private void initComponents() {

		mainPanel = new javax.swing.JPanel();
		optionsFlowPanel = new javax.swing.JPanel();
		optionPanel1 = new javax.swing.JPanel();
		jLabel1 = new javax.swing.JLabel();
		urlField = new javax.swing.JTextField();
		goButton = new javax.swing.JButton();
		pauseButton = new javax.swing.JButton();
		advanceButton = new javax.swing.JButton();
		useProxyCheck = new javax.swing.JCheckBox();
		jPanel1 = new javax.swing.JPanel();
		optionLabel = new javax.swing.JLabel();
		maxDepthLabel = new javax.swing.JLabel();
		maxDepthField = new javax.swing.JTextField();
		jLabel2 = new javax.swing.JLabel();
		maxNodeLabel = new javax.swing.JLabel();
		maxNodeField = new javax.swing.JTextField();
		graphDetailLabel = new javax.swing.JLabel();
		graphDetailComboBox = new javax.swing.JComboBox();
		minimizeButton = new javax.swing.JButton();
		redrawButton = new javax.swing.JButton();
		graphPanel = new javax.swing.JPanel();
		statusPanel = new javax.swing.JPanel();
		nodeCountLabel = new javax.swing.JLabel();
		countLabel = new javax.swing.JLabel();
		jProgressBar_MainFrame = new javax.swing.JProgressBar();
		menuBar = new javax.swing.JMenuBar();
		fileMenu = new javax.swing.JMenu();
		newOption = new javax.swing.JMenuItem();
		loadOption = new javax.swing.JMenuItem();
		saveOption = new javax.swing.JMenuItem();
		exitMenu = new javax.swing.JMenuItem();
		optionMenu = new javax.swing.JMenu();
		placeholderAction = new javax.swing.JMenuItem();

		setTitle("Web Crawler");
		setMinimumSize(new java.awt.Dimension(950, 600));
		setName("Main Frame"); // NOI18N
		getContentPane().setLayout(
				new javax.swing.BoxLayout(getContentPane(),
						javax.swing.BoxLayout.Y_AXIS));

		mainPanel.setLayout(new javax.swing.BoxLayout(mainPanel,
				javax.swing.BoxLayout.Y_AXIS));

		optionsFlowPanel.setPreferredSize(new java.awt.Dimension(866, 80));
		optionsFlowPanel.setLayout(new java.awt.FlowLayout(
				java.awt.FlowLayout.LEFT, 2, 2));

		optionPanel1.setMaximumSize(new java.awt.Dimension(2000, 40));
		optionPanel1
				.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT));

		jLabel1.setText(" URL :");
		optionPanel1.add(jLabel1);

		urlField.setText("http://www.google.com");
		urlField.setPreferredSize(new java.awt.Dimension(450, 20));
		optionPanel1.add(urlField);

		goButton.setText("Go");
		goButton.setFocusable(false);
		goButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
		goButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
		goButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				goButtonActionPerformed(evt);
			}
		});
		optionPanel1.add(goButton);

		pauseButton.setText("Pause");
		pauseButton.setFocusable(false);
		pauseButton
				.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
		pauseButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
		pauseButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				pauseButtonActionPerformed(evt);
			}
		});
		optionPanel1.add(pauseButton);

		advanceButton.setText("Advanced");
		advanceButton.setFocusable(false);
		advanceButton
				.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
		advanceButton
				.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
		advanceButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				advanceButtonActionPerformed(evt);
			}
		});
		optionPanel1.add(advanceButton);

		useProxyCheck.setText("Use Proxy");
		useProxyCheck.setFocusable(false);
		useProxyCheck
				.setHorizontalTextPosition(javax.swing.SwingConstants.RIGHT);
		useProxyCheck.setPreferredSize(new java.awt.Dimension(85, 30));
		useProxyCheck
				.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
		optionPanel1.add(useProxyCheck);

		optionsFlowPanel.add(optionPanel1);

		jPanel1.setMaximumSize(new java.awt.Dimension(2000, 40));
		jPanel1.setMinimumSize(new java.awt.Dimension(600, 100));
		jPanel1.setPreferredSize(new java.awt.Dimension(927, 33));
		jPanel1.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.LEFT, 7,
				5));

		optionLabel.setText(" Options:");
		jPanel1.add(optionLabel);

		maxDepthLabel.setText(" Max Depth");
		jPanel1.add(maxDepthLabel);

		maxDepthField.setText("5");
		maxDepthField.setPreferredSize(new java.awt.Dimension(40, 20));
		maxDepthField.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				maxDepthFieldActionPerformed(evt);
			}
		});
		jPanel1.add(maxDepthField);

		jLabel2.setText(" or");
		jPanel1.add(jLabel2);

		maxNodeLabel.setText(" Max Node");
		jPanel1.add(maxNodeLabel);

		maxNodeField.setText("75");
		maxNodeField.setPreferredSize(new java.awt.Dimension(40, 20));
		jPanel1.add(maxNodeField);

		graphDetailLabel
				.setText("                                        Graph Detail");
		jPanel1.add(graphDetailLabel);

		graphDetailComboBox.setModel(new javax.swing.DefaultComboBoxModel(
				new String[] { "Full", "Reduced", "Item 3", "Item 4" }));
		graphDetailComboBox.setPreferredSize(new java.awt.Dimension(65, 20));
		graphDetailComboBox
				.addActionListener(new java.awt.event.ActionListener() {
					public void actionPerformed(java.awt.event.ActionEvent evt) {
						graphDetailComboBoxActionPerformed(evt);
					}
				});
		jPanel1.add(graphDetailComboBox);

		minimizeButton.setText("Minimize Graph");
		minimizeButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				minimizeButtonActionPerformed(evt);
			}
		});
		jPanel1.add(minimizeButton);

		redrawButton.setText("Redraw Graph");
		redrawButton.setFocusable(false);
		redrawButton
				.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
		redrawButton.setVerticalTextPosition(javax.swing.SwingConstants.BOTTOM);
		redrawButton.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				redrawButtonActionPerformed(evt);
			}
		});
		jPanel1.add(redrawButton);

		optionsFlowPanel.add(jPanel1);

		mainPanel.add(optionsFlowPanel);

		graphPanel.setBackground(new java.awt.Color(255, 255, 255));
		graphPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder());
		graphPanel.setMinimumSize(new java.awt.Dimension(100, 100));
		graphPanel.setPreferredSize(new java.awt.Dimension(800, 600));
		graphPanel.setLayout(new java.awt.BorderLayout());
		mainPanel.add(graphPanel);

		nodeCountLabel.setText(" Node Count:");

		countLabel.setText("0");

		javax.swing.GroupLayout statusPanelLayout = new javax.swing.GroupLayout(
				statusPanel);
		statusPanel.setLayout(statusPanelLayout);
		statusPanelLayout
				.setHorizontalGroup(statusPanelLayout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								statusPanelLayout
										.createSequentialGroup()
										.addContainerGap()
										.addComponent(nodeCountLabel)
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
										.addComponent(
												countLabel,
												javax.swing.GroupLayout.PREFERRED_SIZE,
												53,
												javax.swing.GroupLayout.PREFERRED_SIZE)
										.addPreferredGap(
												javax.swing.LayoutStyle.ComponentPlacement.RELATED,
												700, Short.MAX_VALUE)
										.addComponent(
												jProgressBar_MainFrame,
												javax.swing.GroupLayout.PREFERRED_SIZE,
												159,
												javax.swing.GroupLayout.PREFERRED_SIZE)
										.addContainerGap()));
		statusPanelLayout
				.setVerticalGroup(statusPanelLayout
						.createParallelGroup(
								javax.swing.GroupLayout.Alignment.LEADING)
						.addGroup(
								statusPanelLayout
										.createSequentialGroup()
										.addContainerGap()
										.addGroup(
												statusPanelLayout
														.createParallelGroup(
																javax.swing.GroupLayout.Alignment.TRAILING)
														.addGroup(
																statusPanelLayout
																		.createParallelGroup(
																				javax.swing.GroupLayout.Alignment.BASELINE)
																		.addComponent(
																				nodeCountLabel)
																		.addComponent(
																				countLabel))
														.addComponent(
																jProgressBar_MainFrame,
																javax.swing.GroupLayout.PREFERRED_SIZE,
																javax.swing.GroupLayout.DEFAULT_SIZE,
																javax.swing.GroupLayout.PREFERRED_SIZE))
										.addContainerGap()));

		mainPanel.add(statusPanel);

		getContentPane().add(mainPanel);

		fileMenu.setText("File");

		newOption.setText("New");
		newOption.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				newOptionActionPerformed(evt);
			}
		});
		fileMenu.add(newOption);

		loadOption.setText("Load");
		loadOption.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				loadOptionActionPerformed(evt);
			}
		});
		fileMenu.add(loadOption);

		saveOption.setText("Save");
		saveOption.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				saveOptionActionPerformed(evt);
			}
		});
		fileMenu.add(saveOption);

		exitMenu.setText("Exit");
		exitMenu.addActionListener(new java.awt.event.ActionListener() {
			public void actionPerformed(java.awt.event.ActionEvent evt) {
				exitMenuActionPerformed(evt);
			}
		});
		fileMenu.add(exitMenu);

		menuBar.add(fileMenu);

		optionMenu.setText("Option");

		placeholderAction.setText("Placeholder");
		placeholderAction
				.addActionListener(new java.awt.event.ActionListener() {
					public void actionPerformed(java.awt.event.ActionEvent evt) {
						placeholderActionActionPerformed(evt);
					}
				});
		optionMenu.add(placeholderAction);

		menuBar.add(optionMenu);

		setJMenuBar(menuBar);

		pack();
	}// </editor-fold>//GEN-END:initComponents

	private void redrawButtonActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_redrawButtonActionPerformed
		// TODO add your handling code here:
		System.out.println("Redraw Button Pressed");
		RedrawGraph();
	}// GEN-LAST:event_redrawButtonActionPerformed

	private static WebCrawler crawler;
	private DirectedGraph<URL, Integer> graph;
	private GraphDatabase graphDB = new GraphDatabase();
	private BasicVisualizationServer<URL, Integer> vs;

	private void setupWebCrawler() {

		// crawler = new WebCrawler(this.useProxyCheck.isSelected());
		crawler = null;
		graph = null;
		crawler = new WebCrawler(this.useProxyCheck.isSelected());
		crawler.setMaxDepth(Integer.parseInt(this.maxDepthField.getText()));
		crawler.setMaxUrls(Integer.parseInt(this.maxNodeField.getText()));

		graph = crawler.getGraph();

		
		
		// final boolean isMaxURLs = true;
		crawler.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				//crawler.
				
				CrawlerFoundMoreURLs();
			}
		});

		// Layout<URL, Integer> layout = new FRLayout2<URL, Integer>(graph);
		// layout.setSize(new Dimension(800,800)); // sets the initial size of
		// the layout space
		// Dimension preferredSize = new Dimension(1000,1000);
		// vs = new BasicVisualizationServer<URL, Integer>(layout,
		// preferredSize);
		// vs.getRenderContext().setVertexLabelTransformer(new
		// ToStringLabeller<URL>());
	}

	double redrawCount = 1;

	public void CrawlerFoundMoreURLs() {
		// graph = crawler.getGraph();
		Integer vertexCount = graph.getVertexCount();

		
		// if(vertexCount<1){
		// This stops stack overflow when trying to draw graph 100 times hwne
		// empty
		// return;
		// }

		 System.out.println("Found More "+vertexCount);
		this.nodeCountLabel.setText("Node count: " + vertexCount.toString());

		if (vertexCount > redrawCount) {
			redrawCount = redrawCount * 3;
			RedrawGraph();
		}

	}

	//Advanced URLS are stored here
	public ArrayList<String> advancedURLS = new ArrayList<String>();
	//Advanced URLS are stored here
	private void goButtonActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_goButtonActionPerformed
		// TODO add your handling code here:
		System.out.println("Go Button Pressed");
		setupWebCrawler();
		jProgressBar_MainFrame.setIndeterminate(true);

		// jScrollPane_GraphDrawingArea.removeAll();
		System.out.println("Starting the Crawler");
		// Submit URL to crawler
		try {
			crawler.submit(this.urlField.getText());
			if(advancedURLS.size()>0){
				System.out.println("Starting the Crawler, with addtional URLS");
				for(String s : advancedURLS)
				{
					crawler.submit(s);
				}
			}

			// drawGraph(graph);
		} catch (MalformedURLException e) {
			e.printStackTrace();
		} catch (FoundMaxException e) {
			e.printStackTrace();
		}
	}// GEN-LAST:event_goButtonActionPerformed

	private void loadOptionActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_loadOptionActionPerformed
		// TODO add your handling code here:
		LoadFrame loadFrame = new LoadFrame(this);
		loadFrame.setVisible(true);

		// this.jDialog_LoadGraph.setVisible(false);

		System.out.println("Load Action Pressed");
	}// GEN-LAST:event_loadOptionActionPerformed

	public void loadGraph(String fname) {
		System.out.println("Trying to load graph");
		// int SelectedGraphIndex = loadFrame.getJlist().getSelectedIndex();
		// jProgressBar_MainFrame.setIndeterminate(true);
		
		DirectedGraph<URL, Integer> loadedGraph;
		try {
			System.out.println("Graph Should now load " + fname);
			loadedGraph = graphDB.loadCustomGraph(fname);
			graph = loadedGraph;
			graphPanel.removeAll();
			drawGraph(graph);

		} catch (Exception e) {
			System.out.println("Graph failed to load");
			e.printStackTrace();
			return;
		}
		jProgressBar_MainFrame.setIndeterminate(false);

	}
	
	public void addAdvancedURLS(DefaultListModel dlModel){
		//advancedURLS
		for(int i=0;i<dlModel.size();i++){
			advancedURLS.add((String)dlModel.get(i));
		}
		
	}

	public void saveGraph(String fname) {
		JFrame frame = new JFrame();
		jProgressBar_MainFrame.setIndeterminate(true);
		if (!fname.matches("")) {
			if (graphDB.saveGraph(fname, graph)) {
				JOptionPane.showMessageDialog(frame, "Save succeed");
			} else {
				JOptionPane.showMessageDialog(frame, "Error saving on graph",
						"Error", JOptionPane.ERROR_MESSAGE);
			}
		} else {
			JOptionPane.showMessageDialog(frame,
					"Error on saving on graph, no name entered", "Error",
					JOptionPane.ERROR_MESSAGE);
		}
		jProgressBar_MainFrame.setIndeterminate(false);

	}

	private void drawGraph(DirectedGraph<URL, Integer> passedGraph) {

		if(passedGraph==null){
			graphPanel.removeAll();
			graphPanel.revalidate();
			return;
		}
		
		if (graphDetailComboBox.getSelectedIndex() == 1) {
			passedGraph = minimizeGraph();
		}
		AbstractLayout<URL, Integer> layout = new FRLayout2<URL, Integer>(
				passedGraph);

		// Set graph redraw speed depending on graph size.
		((FRLayout2) layout).setMaxIterations(10);

		int nodeCount = passedGraph.getVertexCount();

		//scale factor for graph drawing pane
		double scaleFactorD = nodeCount*0.0015;
		int scaleFactor = (int)(nodeCount*0.0015)+1;
		System.out.println("Scale factor is "+scaleFactor);
		if(scaleFactor>4){
			scaleFactor = 4;
		}
		scaleFactor =1;
		
		//int newWidth= graphPanel.getBounds().width*scaleFactor;
		//int newHeight = graphPanel.getBounds().height*scaleFactor;
		
		
		
		
		
		
		if (nodeCount < 300) {
			((FRLayout2) layout).setMaxIterations(50);
		}

		if (nodeCount < 150) {
			((FRLayout2) layout).setMaxIterations(150);
		}

		if (nodeCount < 80) {
			((FRLayout2) layout).setMaxIterations(200);
		}

		if (nodeCount < 20) {
			((FRLayout2) layout).setMaxIterations(300);
		}

		VisualizationViewer<URL, Integer> vv = new VisualizationViewer<URL, Integer>(
				layout, new Dimension(graphPanel.getBounds().width *scaleFactor,
						graphPanel.getBounds().height *scaleFactor));

		// JRootPane rp = graphPanel.getRootPane();
		// rp.putClientProperty("defeatSystemEventQueueCheck", Boolean.TRUE);

		vv.setLayout(new BorderLayout());
		vv.setBackground(java.awt.Color.white);
		vv.setFont(new Font("Serif", Font.PLAIN, 12));
		vv.getModel().getRelaxer().setSleepTime(500);
		vv.setGraphMouse(new DefaultModalGraphMouse<URL, Integer>());

		Transformer<URL, String> nodeLabelTransform = new Transformer<URL, String>() {
			public String transform(URL url) {
				String str = url.getHost();
				return str;
			}
		};
		// VisualizationViewer.ToolTipListener test;
		// vv.setToolTipListener(vv);
		Transformer<URL, String> vertexTooltips = new Transformer<URL, String>() {
			public String transform(URL url) {
				String urlString = url.toString();
				// This is how you do multi line tool tips, seperate with <p>
				// How to make clickable?
				return ("<html>Full URL<p><A HREF=\"" + urlString + "\">"
						+ urlString + "</A>");
			}
		};

		vv.setVertexToolTipTransformer(vertexTooltips);

		// ToolTipFunction

		// Transformer<URL, Paint> nodeColorTransform =
		// new Transformer<URL, Paint>()
		// {
		// public Paint transform(URL url) {
		// int n=0;
		// boolean matched = false;
		// Random rand = new Random();
		// Color nodeColor = new Color(rand.nextInt(255), rand.nextInt(255),
		// rand.nextInt(255));
		// List nodeList = new ArrayList <String>();
		// Color colorList [] = new Color[1000] ;
		// if (!nodeList.isEmpty()){
		// while (nodeList.listIterator().hasNext() && matched==false){
		// //if the new node name is found in list,
		// //the colour of new node will set to be same as the group it belong
		// to.
		// if (url.getHost().matches(nodeList.toString())){
		// int i = nodeList.indexOf(nodeList.iterator().next());
		// Color c = colorList[i];
		// matched = true;
		// return c;
		// }
		// }
		// if (matched==false){
		// //if the new node name is not found in list,
		// //then a new colour is given to the new node
		// nodeList.add(url.getHost());
		// colorList[n]= nodeColor;
		// return nodeColor;
		// }
		// }
		// //The first node is given a random colour.
		// nodeList.add(url.getHost());
		// colorList[n] = nodeColor;
		// return nodeColor;
		// }
		// };

		Transformer<URL, Paint> nodeColorTransform = new Transformer<URL, Paint>() {
			public Paint transform(URL url) {
				URL shortURL = null;
				URL shortURL2 = null;
				try {
					shortURL = new URL("http://" + url.getHost() + "/");
					shortURL2 = new URL("http://" + url.getHost());
					// System.out.println("Start url "+url.toString()+" compared to final "+shortURL.toString());
				} catch (MalformedURLException e) {
					System.out.println("Problem getting URL for color");
					e.printStackTrace();
				}

				if (shortURL == null) {
					return Color.RED;
				}

				if (shortURL.equals(url) || shortURL2.equals(url)) {
					return Color.GREEN;
				} else {
					return Color.RED;
				}
			}
		};

		vv.getRenderer().getVertexLabelRenderer().setPosition(
				Renderer.VertexLabel.Position.S);
		vv.getRenderContext().setVertexLabelTransformer(nodeLabelTransform);
		vv.getRenderContext().setVertexFillPaintTransformer(nodeColorTransform);
		vv.setForeground(new java.awt.Color(0, 0, 0));
		graphPanel.removeAll();
		graphPanel.add(new GraphZoomScrollPane(vv));
		Integer vertexCount = passedGraph.getVertexCount();
		nodeCountLabel.setText("Node count: " + vertexCount.toString());
		graphPanel.revalidate();
	}

	private DirectedGraph<URL, Integer> minimizeGraph() {

		
		
		// Pause crawler
		DirectedGraph<URL, Integer> orgGraph = graph;
		
		// Unpause
		DirectedGraph<URL, Integer> newGraph = new DirectedSparseMultigraph<URL, Integer>();
		HashSet<URL> storedVertices = new HashSet<URL>();
		HashSet<Pair<URL>> storedEdges = new HashSet<Pair<URL>>();
		int edgeCount = 0;

		// EdgeType et = EdgeType.DIRECTED;
		Collection<URL> vertices = orgGraph.getVertices();
		Collection<Integer> edges = orgGraph.getEdges(orgGraph.getEdgeType(0));

		Iterator edgesIter = edges.iterator();
		Iterator verticesIter = vertices.iterator();

		while (verticesIter.hasNext()) {
			URL newURL = (URL) verticesIter.next();
			try {
				newURL = new URL("http://" + newURL.getHost());
			} catch (MalformedURLException e) {
				System.out.println("Problem converting to URL");
				e.printStackTrace();
			}

			if (storedVertices.add(newURL)) {
				newGraph.addVertex(newURL);
			}
		}

		while (edgesIter.hasNext()) {
			// Pair<URL> newEdge = (Pair<URL>)edgesIter.next();
			int edgeIndex = (Integer) edgesIter.next();
			// Pair<URL> newEdge = graph.getDest(edgeIndex);

			URL source = orgGraph.getSource(edgeIndex);
			URL dest = orgGraph.getDest(edgeIndex);

			if (source == null || dest == null) {
				System.out.println("Null source or dest");
				continue;
			}
			// System.out.println("Source "+graph.getSource(edgeIndex));

			try {
				source = new URL("http://"
						+ orgGraph.getSource(edgeIndex).getHost());
				dest = new URL("http://"
						+ orgGraph.getDest(edgeIndex).getHost());
			} catch (MalformedURLException e) {
				System.out.println("Problem converting pairs");
				e.printStackTrace();
			}

			Pair<URL> finalEdge = new Pair<URL>(source, dest);

			if (storedEdges.add(finalEdge)) {
				newGraph.addEdge(edgeCount, source, dest);
				edgeCount++;
			}

		}

		storedVertices.clear();
		storedEdges.clear();

		return newGraph;

	}

	private void RedrawGraph() {
		System.out.println("Redrawing");
		// Put code here to only show progress bar if not already working
		if (jProgressBar_MainFrame.isIndeterminate()) {
			drawGraph(graph);
			graphPanel.revalidate();
		} else {
			jProgressBar_MainFrame.setIndeterminate(true);
			drawGraph(graph);
			graphPanel.revalidate();
			jProgressBar_MainFrame.setIndeterminate(false);
		}

	}

	private void saveOptionActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_saveOptionActionPerformed
		// TODO add your handling code here:
		SaveFrame saveFrame = new SaveFrame(this);
		saveFrame.setVisible(true);
		System.out.println("Save Action Pressed");

		// HACK merge to one line THIS IS NEED TO SAVE TO XML, removes "&"
		// symbol

		// System.out.println("OLD URL "+absoluteUrl);

		// String newURL = absoluteUrl.replaceAll("&amp;", "&");

		// absoluteUrl = newURL.replaceAll("&", "&amp;");

		// System.out.println("NEW URL "+absoluteUrl);

	}// GEN-LAST:event_saveOptionActionPerformed

	private void placeholderActionActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_placeholderActionActionPerformed
		// TODO add your handling code here:

	}// GEN-LAST:event_placeholderActionActionPerformed
	
	boolean crawlerIsPaused = false;
	private void pauseButtonActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_stopButtonActionPerformed
		System.out.println("It's " + crawlerIsPaused + "!");
		
		if (crawlerIsPaused) {
			// It's paused! Unpausing now.
			crawler.unpause();
			crawlerIsPaused = false;
			pauseButton.setText("Pause");
		}
		else {
			// It's unpaused! Pausing now.
			crawler.pause();
			crawlerIsPaused = true;
			pauseButton.setText("Unpause");
		}

		jProgressBar_MainFrame.setIndeterminate(false);
	}// GEN-LAST:event_pauseButtonActionPerformed

	private void advanceButtonActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_advanceButtonActionPerformed
		// TODO add your handling code here:
		OptionFrame optionFrame = new OptionFrame(this);
		optionFrame.setVisible(true);
		System.out.println("Advanced Button Pressed");
	}// GEN-LAST:event_advanceButtonActionPerformed

	private void exitMenuActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_exitMenuActionPerformed
		// TODO add your handling code here:
		System.exit(0);
	}// GEN-LAST:event_exitMenuActionPerformed

	private void newOptionActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_newOptionActionPerformed
		// TODO add your handling code here:
		//MainFrame m = new MainFrame();
		//m.setVisible(true);
		this.graph = null;
		crawler = null;
		this.advancedURLS.clear();
		this.drawGraph(graph);
		this.graphPanel.revalidate();
		this.crawlerIsPaused = false;
		this.jProgressBar_MainFrame.setIndeterminate(false);
		this.redrawCount = 1;
		
		
	}// GEN-LAST:event_newOptionActionPerformed

	private void maxDepthFieldActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_maxDepthFieldActionPerformed
		// TODO add your handling code here:
	}// GEN-LAST:event_maxDepthFieldActionPerformed

	private void graphDetailComboBoxActionPerformed(
			java.awt.event.ActionEvent evt) {// GEN-FIRST:event_graphDetailComboBoxActionPerformed
		// TODO add your handling code here:
		// Combo box changes
	}// GEN-LAST:event_graphDetailComboBoxActionPerformed

	private void minimizeButtonActionPerformed(java.awt.event.ActionEvent evt) {// GEN-FIRST:event_minimizeButtonActionPerformed
		// TODO add your handling code here:
		// Minize Graph
		// minimizeGraph();
		drawGraph(minimizeGraph());
	}// GEN-LAST:event_minimizeButtonActionPerformed

	/**
	 * @param args
	 *            the command line arguments
	 */
	public static void main(String args[]) {
		java.awt.EventQueue.invokeLater(new Runnable() {
			public void run() {
				new MainFrame().setVisible(true);
			}
		});
	}

	// Variables declaration - do not modify//GEN-BEGIN:variables
	private javax.swing.JButton advanceButton;
	private javax.swing.JLabel countLabel;
	private javax.swing.JMenuItem exitMenu;
	private javax.swing.JMenu fileMenu;
	private javax.swing.JButton goButton;
	private javax.swing.JComboBox graphDetailComboBox;
	private javax.swing.JLabel graphDetailLabel;
	private javax.swing.JPanel graphPanel;
	private javax.swing.JLabel jLabel1;
	private javax.swing.JLabel jLabel2;
	private javax.swing.JPanel jPanel1;
	javax.swing.JProgressBar jProgressBar_MainFrame;
	private javax.swing.JMenuItem loadOption;
	private javax.swing.JPanel mainPanel;
	private javax.swing.JTextField maxDepthField;
	private javax.swing.JLabel maxDepthLabel;
	private javax.swing.JTextField maxNodeField;
	private javax.swing.JLabel maxNodeLabel;
	private javax.swing.JMenuBar menuBar;
	private javax.swing.JButton minimizeButton;
	private javax.swing.JMenuItem newOption;
	private javax.swing.JLabel nodeCountLabel;
	private javax.swing.JLabel optionLabel;
	private javax.swing.JMenu optionMenu;
	private javax.swing.JPanel optionPanel1;
	private javax.swing.JPanel optionsFlowPanel;
	private javax.swing.JMenuItem placeholderAction;
	private javax.swing.JButton redrawButton;
	private javax.swing.JMenuItem saveOption;
	private javax.swing.JPanel statusPanel;
	private javax.swing.JButton pauseButton;
	private javax.swing.JTextField urlField;
	private javax.swing.JCheckBox useProxyCheck;
	// End of variables declaration//GEN-END:variables

}
